#include "log_publish.hpp"
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <algorithm>

LogPublish::LogPublish() 
{

}

LogPublish::~LogPublish() 
{
    deinit();
}

int LogPublish::init() 
{
    // 1. 创建套接字
    m_sock_fd = socket(AF_INET, SOCK_STREAM, 0);

    // 2. 绑定 sock_fd
    struct sockaddr_in my_addr;
    bzero(&my_addr, sizeof(my_addr));
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(SOCK_PORT); 
    my_addr.sin_addr.s_addr = htonl(INADDR_ANY); 
    bind(m_sock_fd, (struct sockaddr*)&my_addr, sizeof(my_addr));

    // 3. 监听 listen
    listen(m_sock_fd, OPEN_MAX);
}

int LogPublish::deinit()
{
    stop();
}

int LogPublish::start()
{
    m_loop_run = true;
    m_th_publish = std::thread([this](std::atomic_bool* loop_run){
        int ret, num_events = 0;
        
        char buff[RECV_BUFF_MAX];
        int buff_len;

        struct epoll_event event;
        struct epoll_event wait_event;

        struct sockaddr_in cli_addr;
        int cli_len = sizeof(cli_addr);

        int ep_fd = epoll_create(OPEN_MAX + 1);
        if (-1 == ep_fd) {
            printf("epoll_create failed: %s\n", strerror(errno));
            exit(EXIT_FAILURE);
        }

        event.data.fd = m_sock_fd;
        event.events = EPOLLIN;

        ret = epoll_ctl(ep_fd, EPOLL_CTL_ADD, m_sock_fd, &event);
        if (-1 == ret) {
            printf("epoll_ctl EPOLL_CTL_ADD failed: %s", strerror(errno));
            exit(EXIT_FAILURE);
        }

        while (m_loop_run) {
            num_events = epoll_wait(ep_fd, &wait_event, 1, 1000);

            if (num_events == 0) {} // 超时
            if (num_events < 0) {} // 异常

            // 新连接
            if ((m_sock_fd == wait_event.data.fd) && (EPOLLIN == wait_event.events)) {

                int conn_fd = accept(m_sock_fd, (struct sockaddr *)&cli_addr, (socklen_t*)&cli_len);
                if (conn_fd < 0) {
                    printf("accept connnect faild: %s\n", strerror(errno));
                    continue;
                } else {
                    // m_fds.push_back(conn_fd);
                    std::list<int>::iterator it = std::lower_bound(m_fds.begin(), m_fds.end(), conn_fd);
                    m_fds.insert(it, conn_fd);

                    event.data.fd = conn_fd;
                    event.events = EPOLLIN;

                    ret = epoll_ctl(ep_fd, EPOLL_CTL_ADD, conn_fd, &event);
                    if (-1 == ret) {
                        printf("epoll_ctl EPOLL_CTL_ADD failed: %s\n", strerror(errno));
                        return;
                    }
                }

                --num_events;
                if (num_events <= 0) continue;
            }

            // 响应客户端
            std::list<int>::iterator it = std::find(m_fds.begin(), m_fds.end(), wait_event.data.fd);
            if (it != m_fds.end()) { // 找到元素
                buff_len = recv(*it, buff, RECV_BUFF_MAX, 0);
                if (buff_len < 0) {
                    if (errno == ECONNRESET) {  // 连接超时
                        close(*it);
                        m_fds.erase(it);
                    } else {
                        printf("read faild: %s\n", strerror(errno));
                    }
                } else if (buff_len == 0) {  // Client 关闭连接
                    close(*it);
                    m_fds.erase(it);
                } else {
                    // 正常接收到客户端数据，进行处理
                }
            }


            // for (i = 1; i <= maxi; i++) {
            //     if (m_fds[i] < 0) continue;

            //     if ((m_fds[i] = wait_event.data.fd) && (EPOLLIN == wait_event.events & (EPOLLIN | EPOLLERR))) {
            //         int len = 0;
            //         char buf[128] = {0};

            //         if ((len = recv(m_fds[i], buf, sizeof(buf), 0)) < 0) {
            //             if (errno == ECONNRESET) {  // 超时
            //                 close(m_fds[i]);
            //                 m_fds[i] = -1;
            //             } else {
            //                 printf("read faild: %s\n", strerror(errno));
            //             }
            //         } else if (len == 0) {  // client 关闭连接
            //             close(m_fds[i]);
            //             m_fds[i] = -1;
            //         } else {
            //             // 正常接收到客户端数据，进行处理
            //         }

            //         if (--ret <= 0) break;
            //     }
            // }
        }

        close(ep_fd);

        // 关闭所有客户端连接
        for (i = 0; i < OPEN_MAX; ++i) {
            if (m_fds[i] >= 0) {
                close(m_fds[i]);
                m_fds[i] = -1;
            }
        }

        return;
    });
}

int LogPublish::stop()
{
    m_loop_run = false;
    if (m_th_publish.joinable()) {
        m_th_publish.join();
    }
}